<template>
  <div class="w-100">
    <template v-if="fileQueueRefreshed">
      <div class="d-flex" v-for="(v,i) in fileQueue">
        <div>
          <el-input :readonly="readonly" :disabled="disabled" v-model="fileQueue[i].value"
                    @change="handleOnInputChange">
            <template v-slot:prepend>
              <el-button size="mini" @click="preview(fileQueue[i].value)"><i class="el-icon-view"></i>
              </el-button>
            </template>
            <template v-slot:append>
              <el-button @click="selectFileToUploader(i)">{{ dataButtonText }}</el-button>
            </template>
          </el-input>
        </div>


        <div style="width:24px" class=" me-2">
          <el-icon style="cursor: pointer;" class="text-danger mt-1" v-if="multiple && i > 0" :size="24"
                   @click="removeInput(i)">
            <Delete/>
          </el-icon>
        </div>
        <div class="d-flex flex-grow-1 ">
          <template v-if="fileQueue[i].queueItem">
            <div class="flex-grow-1">
              <el-progress :text-inside="true" :stroke-width="32" stroke-linecap="butt"
                           :percentage="fileQueue[i].queueItem.chunksCompletedPercent"
                           :format="progressContent(fileQueue[i].queueItem.file.name)"
              >
              </el-progress>
            </div>
            <div>
              <i v-if="!fileQueue[i].queueItem.uploadCompleted" class="el-icon-circle-close"
                 style="cursor: pointer;font-size: 28px" @click="cancelUpload(i)"></i>
            </div>
          </template>
        </div>

      </div>
    </template>

    <div>
      <el-button v-if="multiple" type="info" plain size="small" @click="addInput">添加文件</el-button>
    </div>

  </div>

</template>

<script>
import {Uploader, Utils} from 'js-utils';

export default {
  components: {},
  props: {
    generateTokenCallback: {
      type: Function,
      default: ()=>{
        return Promise.reject(new Error("token回调必传"))
      }
    },
    previewCallback: {
      type: Function,
      default: null
    },
    dataValue: {
      type: Array,
      default: () => {
        return []
      }
    },
    multiple: { //多个文件
      type: Boolean,
      default: false
    },

    dataButtonText: {
      type: String,
      default: '上传'
    },
    disabled: {
      type: Boolean,
      default: false
    },
    readonly: {
      type: Boolean,
      default: false
    }
  },
  data() {
    return {
      uploader: new Uploader("", true),
      fileQueue: [],
      fileQueueRefreshed: true
    }
  },
  created() {
    let _this = this;
    if (Utils.typeIs('array', _this.dataValue) && _this.dataValue.length > 0) {
      if (_this.multiple) {
        _this.fileQueue = [{
          value: _this.dataValue[0],
          canceled:false,
          queueItem: null
        }]
      } else {
        _this.dataValue.forEach(function (v) {
          _this.fileQueue.push({
            value: v,
            canceled:false,
            queueItem: null
          })
        })
      }

    } else {
      _this.fileQueue = [{
        value: "",
        canceled:false,
        queueItem: null
      }]
    }

    //设置上传线程
    _this.uploader.setLimitMaxThreads(5)
    //设置错误信息显示回调
    _this.uploader.setEventOnError(function (err) {
      _this.$message.error(err.message)
    })

    _this.uploader.setEventOnFileQueueChange(function (queue, changedIndex) {
      queue.forEach(function (queueItem) {
        if(Utils.valueGet(_this.fileQueue,queueItem.customId + '.canceled',false)){
          return
        }
        _this.fileQueue[queueItem.customId].queueItem = queueItem
        if (queueItem.uploadCompleted) {
          _this.fileQueue[queueItem.customId].value = queueItem.url
        }
      })
      _this.handleOnInputChange()
    })

    _this.uploader.setEventOnUploadFinished(function () {
      _this.$emit("finished", _this.getInputValues())
    })
  },
  mounted() {
    let _this = this;
  },
  methods: {
    preview: function (uri) {
      if (Utils.isEmpty(uri)) {
        return;
      }
      let _this = this;
      if (Utils.typeIs('function', LeUtils.valueGet(_this, "previewCallback"))) {
        return _this.previewCallback(uri)
      }
      Utils.linkClick(uri,"_blank")
      return
    },
    getInputValues: function () {
      let _this = this;
      let values = []
      _this.fileQueue.forEach(function (fq) {
        if ("" !== fq.value) {
          values.push(fq.value)
        }
      })
      return values
    },

    handleOnInputChange: function () {
      let _this = this;
      this.$emit("change", _this.getInputValues())
    },

    selectFileToUploader: function (valueIndex) {
      let _this = this;
      _this.fileQueue[valueIndex].canceled=false
      _this.generateTokenCallback().then(function (res_data) {

        let serviceUrl = Utils.valueGet(res_data, "data.service_url")
        _this.uploader.setServerUrl(serviceUrl)
        let maxSize = Utils.valueGet(res_data, "data.max_size", 0)
        if (maxSize > 0) {
          _this.uploader.setFileLimitMaxSize(maxSize)
        }
        let maxChunkSize = Utils.valueGet(res_data, "data.max_chunk_size", 0)
        if (maxChunkSize > 0) {
          _this.uploader.setChunkSize(maxChunkSize)
        }
        _this.uploader.setFileLimitAllowExt(Utils.valueGet(res_data, "data.allow_ext", []))

        _this.uploader.selectFile(false, !_this.multiple, valueIndex)

      }).catch(function (err) {
        _this.$message.error(err.message)
      })
    },

    addInput: function () {
      let _this = this;
      _this.fileQueue.push({
        value: "",
        canceled: false,
        queueItem: null
      })
    },

    removeInput: function (index) {
      let _this = this;
      _this.fileQueue.splice(index, 1)
      _this.handleOnInputChange()
    },

    cancelUpload: function (index) {
      let _this = this;
      if (_this.fileQueue.length <= index) {
        return
      }

      _this.fileQueue[index].canceled = true

      if (!!_this.fileQueue[index].queueItem) {
        _this.uploader.fileQueueRemove(_this.fileQueue[index].queueItem.taskId)
        _this.fileQueue[index].queueItem = null
      }
      _this.fileQueueRefreshed = false
      _this.$nextTick(function () {
        _this.fileQueueRefreshed = true
      })
    },
    progressContent:function (fileName){
      return function (percentage){
        return percentage + '%   ' + fileName
      }
    }

  }
}


</script>
